import Taro from '@tarojs/taro';

// 存储事件类型
type StorageEventType = 'set' | 'remove' | 'clear';

// 存储事件监听器
type StorageEventListener = (event: {
  type: StorageEventType;
  key?: string;
  oldValue?: any;
  newValue?: any;
}) => void;

/**
 * 存储工具类
 */
class Storage {
  private static listeners: StorageEventListener[] = [];

  /**
   * 设置存储
   * @param key 键
   * @param value 值
   * @param expire 过期时间（秒），不传则永久
   */
  static set<T = any>(key: string, value: T, expire?: number): void {
    try {
      const oldValue = this.get(key);
      
      const data = {
        value,
        expire: expire ? Date.now() + expire * 1000 : null,
      };
      
      Taro.setStorageSync(key, JSON.stringify(data));
      
      // 触发事件
      this.notifyListeners({
        type: 'set',
        key,
        oldValue,
        newValue: value
      });
    } catch (e) {
      console.error('Storage.set Error:', e);
    }
  }

  /**
   * 获取存储
   * @param key 键
   * @param defaultValue 默认值
   */
  static get<T = any>(key: string, defaultValue: T | null = null): T | null {
    try {
      const dataStr = Taro.getStorageSync(key);
      if (!dataStr) return defaultValue;

      const data = JSON.parse(dataStr);
      // 判断是否过期
      if (data.expire && data.expire < Date.now()) {
        this.remove(key);
        return defaultValue;
      }

      return data.value as T;
    } catch (e) {
      console.error('Storage.get Error:', e);
      return defaultValue;
    }
  }

  /**
   * 移除存储
   * @param key 键
   */
  static remove(key: string): void {
    try {
      const oldValue = this.get(key);
      
      Taro.removeStorageSync(key);
      
      // 触发事件
      this.notifyListeners({
        type: 'remove',
        key,
        oldValue
      });
    } catch (e) {
      console.error('Storage.remove Error:', e);
    }
  }

  /**
   * 清空存储
   */
  static clear(): void {
    try {
      Taro.clearStorageSync();
      
      // 触发事件
      this.notifyListeners({
        type: 'clear'
      });
    } catch (e) {
      console.error('Storage.clear Error:', e);
    }
  }
  
  /**
   * 检查是否存在
   * @param key 键
   */
  static has(key: string): boolean {
    try {
      const value = this.get(key);
      return value !== null;
    } catch (e) {
      console.error('Storage.has Error:', e);
      return false;
    }
  }
  
  /**
   * 获取存储信息
   */
  static info(): Taro.getStorageInfoSync.Option {
    try {
      return Taro.getStorageInfoSync();
    } catch (e) {
      console.error('Storage.info Error:', e);
      return { keys: [], currentSize: 0, limitSize: 0 };
    }
  }
  
  /**
   * 添加事件监听器
   * @param listener 监听器函数
   */
  static addEventListener(listener: StorageEventListener): void {
    this.listeners.push(listener);
  }
  
  /**
   * 移除事件监听器
   * @param listener 监听器函数
   */
  static removeEventListener(listener: StorageEventListener): void {
    const index = this.listeners.indexOf(listener);
    if (index > -1) {
      this.listeners.splice(index, 1);
    }
  }
  
  /**
   * 通知所有监听器
   * @param event 事件对象
   */
  private static notifyListeners(event: Parameters<StorageEventListener>[0]): void {
    this.listeners.forEach(listener => listener(event));
  }
}

export default Storage;